%{
#include <stdio.h>
#include "attr.h"
int yylex();
void yyerror(char * s);
#include "symtab.h"

int intpower(int a, int b) 
{ 
  int result, i;
  
  result = 1;
  for (i = b; i > 0; i--)
    result = result * a;
  return result;
}

%}
%union {MyIntType value;
	tokentype token;
        }

%token PROG PERIOD WRITELN BEG END ASG DIV EXP
%token <token> ID NUM

%type <value> exp constant
%start program
%left '+' '-' 
%left '*' DIV
%left EXP

%%
program : PROG ID ';' block PERIOD {addname($2.str);}
	;
block	: BEG stmtlist END
	;
stmtlist : stmtlist ';' stmt
	| stmt
        | error { yyerror("illegal statement \n");}
	;
stmt :    astmt 
        | writestmt 
	;
writestmt: WRITELN '(' exp ')'          {printf("  ANSWER >> %d\n", $3.val);}
	;
astmt : ID ASG exp                      {addname($1.str); setvalue($1.str, $3.val);}
	;
exp	: exp '+' exp		        {addop("+");   $$.val = $1.val + $3.val;}
        | exp '-' exp		        {addop("-");   $$.val = $1.val - $3.val;}
	| exp '*' exp	  	        {addop("*");   $$.val = $1.val * $3.val;}
	| exp DIV exp	                {addop("div"); $$.val = $1.val / $3.val;}
	| exp EXP exp    	        {addop("exp"); $$.val = intpower($1.val, $3.val);}
        | '(' exp ')'                   {$$.val = $2.val;} 
	| ID                            {addname($1.str); $$.val = getvalue($1.str);}
        | constant                      {$$.val = $1.val;}
	| error { yyerror("illegal expression\n");}  
	;
constant: NUM                           {$$.val = $1.num;}  
        ;

%%

void yyerror(char* s) {
        fprintf(stderr,"%s\n",s);
        }

int
main() {
    printf("1\t");
    yyparse();
    printnames();
    printops();
    return 1;
    }
